package com.aiwei.tdjk.controller;

import com.aiwei.tdjk.common.Constants;
import com.aiwei.tdjk.dto.request.DeliveryPagerRequest;
import com.aiwei.tdjk.dto.response.ComparatorMatchHandBookResponse;
import com.aiwei.tdjk.dto.response.MatchHandBookResponse;
import com.aiwei.tdjk.entity.*;
import com.aiwei.tdjk.enums.BookingContainerStatusEnum;
import com.aiwei.tdjk.enums.CustomsHandbookUsedDetailStatusEnum;
import com.aiwei.tdjk.enums.DeliveryStatusEnum;
import com.aiwei.tdjk.enums.SaleOrderStatusEnum;
import com.aiwei.tdjk.service.*;
import com.aiwei.tdjk.utils.SnUtils;
import com.aiwei.tdjk.utils.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Controller
@RequestMapping(value = "/admin/delivery")
public class DeliveryController extends BaseController {

    @Autowired
    private DeliveryService deliveryService;

    @Autowired
    private DeliveryDetailService deliveryDetailService;

    @Autowired
    private BookingContainerService bookingContainerService;

    @Autowired
    private SaleOrderHeaderService saleOrderHeaderService;

    @Autowired
    private SaleOrderItemService saleOrderItemService;

    @Autowired
    private CustomsRefinvstdService customsRefinvstdService;

    @Autowired
    private CustomsHandbookService customsHandbookService;

    @Autowired
    private CustomsHandbookProductdetailService customsHandbookProductdetailService;

    @Autowired
    private CustomsHandbookUsedDetailService customsHandbookUsedDetailService;


    @RequestMapping(value = {"/list"}, method = RequestMethod.GET)
    public String list(DeliveryPagerRequest request, Model model) {
        request.setType(1);
        model.addAttribute("page", deliveryService.find(request));
        model.addAttribute("delivery", request);
        return viewName("list");
    }

    @RequestMapping(value = {"/my"}, method = RequestMethod.GET)
    public String my(DeliveryPagerRequest request, Model model) {
        User user = UserUtil.getUserFromSession();
        request.setUserId(user.getId());
        model.addAttribute("page", deliveryService.find(request));
        model.addAttribute("delivery", request);
        return viewName("list");
    }

    /**
     * @param model
     * @param ids   根据租船订舱的单号指定发货单
     * @return
     */
    @RequestMapping(value = "create", method = RequestMethod.GET)
    public String showCreateForm(Model model, Long ids) {
        model.addAttribute(Constants.OP_NAME, "新增");
        Delivery delivery = new Delivery();
        model.addAttribute("m", delivery);
        //也要加载提单信息栏、商品装箱信息栏目

        BookingContainer bookingContainer = bookingContainerService.get(ids);

        String saleordercode = bookingContainer.getSaleOrderCode();

        SaleOrderHeader saleOrderHeader = saleOrderHeaderService.getBySaleOrderCode(saleordercode);

        List<SaleOrderItem> saleOrderItems = saleOrderItemService.getListByOrderCode(saleordercode);

        model.addAttribute("bookingContainer", bookingContainer);
        model.addAttribute("saleOrderHeader", saleOrderHeader);
        model.addAttribute("saleOrderItems", saleOrderItems);

        //已经制定的发货单的数量、已经发货的订单项目数量
        List<Delivery> listBySaleOrderCode = deliveryService.getListBySaleOrderCode(saleordercode);
        int markedDeliverCount = 0;
        if (listBySaleOrderCode != null)
            markedDeliverCount = listBySaleOrderCode.size();
        model.addAttribute("markedDeliverCount", markedDeliverCount);

        model.addAttribute("hasNotDeliverCount", deliveryService.getHasNotDeliveryItemList(saleordercode));

        return viewName("editForm");
    }

    /**
     * 确定商检
     * @return
     */
    @RequestMapping(value = "create", method = RequestMethod.POST)
    public String create(Model model, Delivery delivery, String saleordercode, String[] saleorderitemcode, Integer[] packingQty, BindingResult result,
                         RedirectAttributes redirectAttributes) {
//		if (hasError(result))
//			return showCreateForm(model);

        //验证是否是否超过了预定的集装箱数量
        List<Delivery> listBySaleOrderCode = deliveryService.getListBySaleOrderCode(saleordercode);
        int markedDeliverCount = 0;
        if (listBySaleOrderCode != null)
            markedDeliverCount = listBySaleOrderCode.size();

        BookingContainer bookingContainer = bookingContainerService.getBySaleOrderCode(saleordercode);
        int totalContainer = bookingContainer.getContainerCount_EQ()+bookingContainer.getContainerCount_HQ();
		if (totalContainer<=markedDeliverCount){
            redirectAttributes.addFlashAttribute(Constants.ERROR, "集装箱数量不足");
            return "redirect:"+"/admin/bookingContainer/list";
        }

        //修改订舱的状态为：分货中、分货完成  分货完成:还差一个满足总数
        if(markedDeliverCount+1==totalContainer){
            bookingContainer.setStatus(BookingContainerStatusEnum.deliveried.getCode());
        }else {
            bookingContainer.setStatus(BookingContainerStatusEnum.delivering.getCode());
        }
        bookingContainerService.update(bookingContainer);

        //验证已经发送的订单项目，是否超过了 todo  前端验证
        HashMap<String, Integer> map = deliveryService.getHasNotDeliveryItemList(saleordercode);

        //保存发货单基本信息、发货单详情
        String sn = "FD" + SnUtils.generate();
        delivery.setDeliveryCode(sn);
        delivery.setSaleOrderCode(saleordercode);
        User user = UserUtil.getUserFromSession();
        delivery.setUserId(user.getId());
        deliveryService.add(delivery);

        //生成发货单详情
        for (int i = 0; i < saleorderitemcode.length; i++) {
            DeliveryDetail deliveryDetail = new DeliveryDetail();
            deliveryDetail.setDeliveryId(delivery.getId().toString());
            deliveryDetail.setSaleOrderItemCode(saleorderitemcode[i]);
            deliveryDetail.setDeliveryQty(packingQty[i]);
            deliveryDetail.setStandard(saleOrderItemService.getStandardBysSaleOrderItemCode(saleorderitemcode[i]));
            deliveryDetailService.add(deliveryDetail);
        }

        bookingContainerService.update(bookingContainer);
        redirectAttributes.addFlashAttribute(Constants.MESSAGE, "新增成功");
        return "redirect:"+"/admin/bookingContainer/list";
    }


    /**
     * 查看发货单对应的商检相关的页面
     * @param id
     * @param model
     * @return
     */
    @RequestMapping(value = "{id}/update", method = RequestMethod.GET)
    public String showUpdateForm(@PathVariable("id") Long id, Model model) {
        model.addAttribute(Constants.OP_NAME, "修改");

        model.addAttribute("deliveryId", id);
        Delivery delivery = deliveryService.get(id);
        model.addAttribute("m", delivery);
        //发货详情
        List<DeliveryDetail> deliveryDetailList = deliveryDetailService.getListByDeliveryId(delivery.getId());
        model.addAttribute("deliveryDetailList", deliveryDetailList);
        //查询订单的情况
        SaleOrderHeader saleOrderHeader = saleOrderHeaderService.getBySaleOrderCode(delivery.getSaleOrderCode());
        model.addAttribute("saleOrderHeader", saleOrderHeader);
        //查询租船订舱的情况
        BookingContainer bookingContainer = bookingContainerService.getBySaleOrderCode(delivery.getSaleOrderCode());
        model.addAttribute("bookingContainer", bookingContainer);

        //转变为海关规格
        HashMap<String,Integer> customsSpecificationsMap = new HashMap();

        for (DeliveryDetail deliveryDetail:deliveryDetailList){
            String standard = deliveryDetail.getStandard();
            String customsStandardByInvStandard = customsRefinvstdService.getCustomsStandardByInvStandard(standard);
            if (customsSpecificationsMap.containsKey(customsStandardByInvStandard)){
                int a = customsSpecificationsMap.get(customsStandardByInvStandard)+deliveryDetail.getDeliveryQty();
                customsSpecificationsMap.put(customsStandardByInvStandard,a);
            }else{
                customsSpecificationsMap.put(customsStandardByInvStandard,deliveryDetail.getDeliveryQty());
            }
        }

        model.addAttribute("customsStandardMap", customsSpecificationsMap);
        Object[] customsStandardValues = customsSpecificationsMap.values().toArray();
        int total=0;
        for (Object o:customsStandardValues){
            total+=((Integer) o);
        }
        //前端显示的数据，规格总量和对应的规格列表
        model.addAttribute("customsStandardValues", customsStandardValues);
        model.addAttribute("customsStandardValuesTotal", total);

        //1、查询可用的手册
        //2、封装对象：是否满足规格需要、满足的数量、可用量的Map集合
        List<CustomsHandbook> customsHandbooks = customsHandbookService.getAllAvailable();

        List<MatchHandBookResponse> matchHandBookList = new ArrayList<>();
        for (CustomsHandbook customsHandbook:customsHandbooks){

            MatchHandBookResponse response = new MatchHandBookResponse();
            response.setCustomerHandBookId(customsHandbook.getId());

            HashMap<String,Integer> map = new HashMap();

            Iterator iter = customsSpecificationsMap.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                Object key = entry.getKey();
                Object val = entry.getValue();
                //根据手册主键、规格，查询手册的具体项目
                CustomsHandbookProductdetail handbookProductdetail = customsHandbookProductdetailService.getByHandBookIdAndSpecifications(customsHandbook.getId(), key.toString());

                //手册有没有这个项目
                int notFrozenCount = 0;
                if (handbookProductdetail==null){
                    response.setFit(false);
                }else {
//                    response.setCustomsHandbookProductdetailId(handbookProductdetail.getId());
                    notFrozenCount = customsHandbookUsedDetailService.getNotFrozenCountByDetailId(handbookProductdetail.getId());
                }
                map.put(key.toString(), notFrozenCount);
                response.setMap(map);
                response.setTotalFitCount(response.getTotalFitCount()+notFrozenCount);
            }
            matchHandBookList.add(response);

        }

        //对手册进行排序  安装手册是否满足和满足的总量
        ComparatorMatchHandBookResponse comparator=new ComparatorMatchHandBookResponse();
        Collections.sort(matchHandBookList, comparator);
        model.addAttribute("matchHandBookList",matchHandBookList);

        //如果商检完成，查看商检的情况:哪个手册占用了哪种规格的手册多少数量
        if (delivery.getStatus()==DeliveryStatusEnum.shangjian.getCode()){
            List<CustomsHandbookUsedDetail> handbookUsedDetails = customsHandbookUsedDetailService.getListByDeliveryId(delivery.getId());
            model.addAttribute("handbookUsedDetails",handbookUsedDetails);
        }

        return viewName("viewForm");

    }

    /**
     *
     * @param id
     * @param customerHandBookIdOnlyOne
     * @param usedCount
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = "{id}/update", method = RequestMethod.POST)
    public String update(@PathVariable("id") Long id,Long customerHandBookIdOnlyOne,
                         Integer[] usedCount,RedirectAttributes redirectAttributes) {

        Long deliveryId = id;
        Delivery delivery = deliveryService.get(deliveryId);
        // 判读发货单的状态是否为锁定状态
        if (delivery.getStatus()!=DeliveryStatusEnum.lock.getCode()){
            redirectAttributes.addFlashAttribute(Constants.ERROR, "请先锁定或者该发货单已经商检完成！");
            return redirectToUrl("list");
        }

        // 判断该手册是否能够满足：消耗的手册数量对比发货单需要的
        List<DeliveryDetail> deliveryDetailList = deliveryDetailService.getListByDeliveryId(delivery.getId());
        //转变为海关规格
        HashMap<String,Integer> customsSpecificationsMap = new HashMap();

        for (DeliveryDetail deliveryDetail:deliveryDetailList){
            String standard = deliveryDetail.getStandard();
            String customsStandardByInvStandard = customsRefinvstdService.getCustomsStandardByInvStandard(standard);
            if (customsSpecificationsMap.containsKey(customsStandardByInvStandard)){
                int a = customsSpecificationsMap.get(customsStandardByInvStandard)+deliveryDetail.getDeliveryQty();
                customsSpecificationsMap.put(customsStandardByInvStandard,a);
            }else{
                customsSpecificationsMap.put(customsStandardByInvStandard,deliveryDetail.getDeliveryQty());
            }
        }



        //该手册对应的海关规格的可用量
        HashMap<String,Integer> map = new HashMap();

        Iterator iter = customsSpecificationsMap.entrySet().iterator();
        int j =0;
        while (iter.hasNext()) {


            Map.Entry entry = (Map.Entry) iter.next();
            Object key = entry.getKey();
            Object val = entry.getValue();

            if ((int)val!=usedCount[j]){
                redirectAttributes.addFlashAttribute(Constants.ERROR, "选择的手册数量与需要的数量不一致");
                return redirectToUrl("list");
            }

            //根据手册主键、规格，查询手册的具体项目
            CustomsHandbookProductdetail handbookProductdetail = customsHandbookProductdetailService.getByHandBookIdAndSpecifications(customerHandBookIdOnlyOne, key.toString());
            //手册有没有这个项目
            int notFrozenCount = 0;
            if (handbookProductdetail==null){
            }else {
                notFrozenCount = customsHandbookUsedDetailService.getNotFrozenCountByDetailId(handbookProductdetail.getId());
            }
            map.put(key.toString(), notFrozenCount);
            j++;
        }


        Object[] objects = map.values().toArray();
        for (int i=0;i<objects.length;i++){
            if ((int)objects[i]<usedCount[i]){
                redirectAttributes.addFlashAttribute(Constants.ERROR, "选择的手册不可用，数量不足！");
                return redirectToUrl("list");
            }
        }

        int i=0;
        for (DeliveryDetail deliveryDetail:deliveryDetailList){

            String standard = deliveryDetail.getStandard();
            String customsStandardByInvStandard = customsRefinvstdService.getCustomsStandardByInvStandard(standard);
            CustomsHandbookUsedDetail usedDetail = new CustomsHandbookUsedDetail();
            usedDetail.setSpecifications(customsStandardByInvStandard);
            usedDetail.setDeliveryId(deliveryId);
            //todo 暂且支持一个手册的扣除
            usedDetail.setUsedQty(deliveryDetail.getDeliveryQty());

            //根据手册主键、规格，查询手册的具体项目
            CustomsHandbookProductdetail handbookProductdetail = customsHandbookProductdetailService.getByHandBookIdAndSpecifications(customerHandBookIdOnlyOne, customsStandardByInvStandard);
            usedDetail.setCustomsHandbookProductdetailId(handbookProductdetail.getId());
            customsHandbookUsedDetailService.add(usedDetail);
            i++;
        }

        //修改发货单状态为：已商检未报关
        delivery.setStatus(DeliveryStatusEnum.shangjian.getCode());
        deliveryService.update(delivery);
        return redirectToUrl("list");

    }


    @RequestMapping(value = "changeStatus/{newStatus}")
    public String changeStatus(
            HttpServletRequest request,
            @RequestParam("ids") Long[] ids,
            @PathVariable("newStatus") DeliveryStatusEnum newStatus,
            RedirectAttributes redirectAttributes) {

        deliveryService.changeStatus(ids, newStatus);

        if (newStatus == DeliveryStatusEnum.lock) {
            redirectAttributes.addFlashAttribute(Constants.MESSAGE, "锁定成功！");
        } else if (newStatus == DeliveryStatusEnum.unlock) {
            redirectAttributes.addFlashAttribute(Constants.MESSAGE, "解锁成功！");
        }
        return redirectToUrl("list");
    }

    /**
     * 仓库人员确认  外销
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = "{id}/confirm")
    public String confirm(@PathVariable("id") Long id,RedirectAttributes redirectAttributes) {
        //确认：修改发货单状态为"已报关"，修改商检相关,手册的使用状态为"已报关"
        Delivery delivery = deliveryService.get(id);
        delivery.setStatus(DeliveryStatusEnum.report.getCode());
        deliveryService.update(delivery);
        //订单修改为："确认"
        SaleOrderHeader saleOrderHeader = saleOrderHeaderService.getBySaleOrderCode(delivery.getSaleOrderCode());
        saleOrderHeader.setOrderstate(SaleOrderStatusEnum.confirmed.getCode().toString());
        saleOrderHeaderService.update(saleOrderHeader);

        List<CustomsHandbookUsedDetail> usedDetails = customsHandbookUsedDetailService.getListByDeliveryId(id);
        if (usedDetails!=null&&usedDetails.size()>0){
            for (CustomsHandbookUsedDetail usedDetail:usedDetails){
                usedDetail.setStatus(CustomsHandbookUsedDetailStatusEnum.declare.getCode());
                customsHandbookUsedDetailService.update(usedDetail);
            }
        }
        return redirectToUrl("list");
    }

    /**
     * 仓库人员撤回  外销
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = "{id}/refuse")
    public String refuse(@PathVariable("id") Long id,RedirectAttributes redirectAttributes) {
        //撤回：修改发货单状态为"撤回"，修改商检相关,手册的使用状态为"作废"=="删除"
        Delivery delivery = deliveryService.get(id);
        delivery.setStatus(DeliveryStatusEnum.refused.getCode());
        deliveryService.update(delivery);

        //订单修改为："仓库撤回"
        SaleOrderHeader saleOrderHeader = saleOrderHeaderService.getBySaleOrderCode(delivery.getSaleOrderCode());
        saleOrderHeader.setOrderstate(SaleOrderStatusEnum.refused.getCode().toString());
        saleOrderHeaderService.update(saleOrderHeader);

        // 删除发货单详情 参照跟单的  退回
        List<Delivery> deliveryList = deliveryService.getListBySaleOrderCode(delivery.getSaleOrderCode());
        deliveryDetailService.deleteListByDeliveryId(deliveryList);

        // 修改订舱的状态：仓库撤回
        BookingContainer bookingContainer = bookingContainerService.getBySaleOrderCode(delivery.getSaleOrderCode());
        bookingContainer.setStatus(BookingContainerStatusEnum.refuse.getCode());
//        删除商检
        List<CustomsHandbookUsedDetail> usedDetails = customsHandbookUsedDetailService.getListByDeliveryId(id);
        if (usedDetails!=null&&usedDetails.size()>0){
            for (CustomsHandbookUsedDetail usedDetail:usedDetails){
                customsHandbookUsedDetailService.delete(usedDetail.getId());
            }
        }
        return redirectToUrl("list");
    }




}
